home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks95
/
NewStuff.sit
/
New Stuff
/
NewStuff Installer
/
NewStuffInit.a
< prev
next >
Wrap
Text File
|
1995-06-23
|
15KB
|
665 lines
; NewStuffInit.a
; by Donald Brown
; a Hack that adds a new menu to the Finder 7.5
; © 1995 CE Software, Inc. All rights reserved.
; WHEN WHO WHAT
BLANKS ON
STRING ASIS
PRINT OFF
INCLUDE 'QuickEqu.a'
INCLUDE 'ToolEqu.a'
INCLUDE 'SysEqu.a'
INCLUDE 'Traps.a'
INCLUDE 'Folders.a'
PRINT ON
PutCodeIn Main Entry
InitEntry BRA Install
StartofInit
jMenuSelect dc.l 0 ;We must patch MenuSelect
jMenuKey dc.l 0 ; and MenuKey
jHFSDisptch dc.l 0 ; and HFSDispatch
jSystemTask dc.l 0 ; and SystemTask
jAlert dc.l 0 ; and Alert
NSMenu dc.l 0 ;this is our menu.
NSMenuID dc.w 0 ;this is the ID we wind up using
MyName dcb.b 32,0 ;remember where we are
MyDir dc.l 0
Myvref dc.w 0
AreWeWatching dc.w 0 ;set to 1 if we're looking for a create, 2 when we have
Lastvrefnum dc.w 0
LastDirID dc.l 0
Lastname dcb.b 256,0
NameToCopy dcb.b 256,0
NDVref dc.w 0 ;vrefnum of our folder
NDDir dc.l 0 ;dirID of our folder
SysFldDir dc.l 0 ;dirID of the system Folder
NDModDate dc.l 0
string Pascal
NDName DC.B 'New Documents'
align 2
dcb.b 32,0
string asis
string Pascal
NewMenuText DC.B 'New'
align 2
dcb.b 32,0
string asis
FromPB dcb.b 1024,0
ToPB dcb.b 1024,0
;
; UpdateOurMenu finds a folder in the system folder named "New Documents", and
; puts the name of each file in the menu
;
UpdateOurMenu
link A6,#-1024
movem.l D2-D7/A2-A4,-(SP)
clr.w -(SP) ;find the system folder
move.w #kOnSystemDisk,-(SP)
move.l #kSystemFolderType,-(SP)
move.w #kCreateFolder,-(SP)
pea NDVref
pea SysFldDir
_FindFolder
tst.w (SP)+
@LookForIt
lea -1024(A6),A0 ;Now, let's find the New Documents folder
lea NDName,A1
move.l A1,ioFileName(A0)
move.w NDVref,ioVRefnum(A0)
move.l SysFldDir,ioDirID(A0)
clr.w ioFDirIndex(A0)
_GetCatInfo
beq.s @DidFind
lea -1024(A6),A0 ;Couldn't find it. Make one.
lea NDName,A1
move.l A1,ioFileName(A0)
move.w NDVref,ioVRefnum(A0)
move.l SysFldDir,ioDirID(A0)
_DirCreate
bne @Done
bra.s @LookForIt
@DidFind
lea NDDir,A1
move.l ioDirID(A0),(A1)
lea NDModDate,A1
move.l ioFlMdDat(A0),A1
@KillLoop
clr.w -(SP)
move.l NSMenu,-(SP) ;if more than two items in the menu, kill one
_CountMItems
move.w (SP)+,D0
cmp.w #2,D0
ble.s @100
move.l NSMenu,-(SP)
move.w #3,-(SP)
_DelMenuItem
bra.s @KillLoop
@100 moveq #1,D7
@SearchLoop
lea -1024(A6),A0 ;OK, we've got to get the list of files
lea -256(A6),A1
move.l A1,ioFileName(A0)
clr.b -256(A6)
move.w NDVref,ioVRefnum(A0)
move.l NDDir,ioDirID(A0)
move.w D7,ioFDirIndex(A0)
_GetCatInfo
tst.w D0
bne.s @Done
move.l NSMenu,-(SP) ;add this name to the menu (even if it has
pea NDName ;characters recognized by AppendMenu, which is why
_AppendMenu ;we're just appending a simple name and then
clr.w -(SP) ;calling SetItem)
move.l NSMenu,-(SP)
_CountMItems
move.w (SP)+,D6
move.l NSMenu,-(SP)
move.w D6,-(SP)
pea -256(A6)
_SetItem
move.l NSMenu,-(SP) ;and let's add control characters
move.w D6,-(SP)
move.w D7,D0
add.w #'0',D0
move.w D0,-(SP)
_SetItemCmd
addq #1,D7
bra.s @SearchLoop
@Done
movem.l (SP)+, D2-D7/A2-A4
unlk A6
rts
;
; Add our items adds the menu to the menu list just before we call MenuSelect/MenuKey
;
AddUsIn
move.w NSMenuID,D0 ;have we added our menu yet?
tst.w D0
beq.s @MustUpdate
lea FromPB,A0 ;Now, let's find the New Documents folder
lea NDName,A1
move.l A1,ioFileName(A0)
move.w NDVref,ioVRefnum(A0)
move.l SysFldDir,ioDirID(A0)
clr.w ioFDirIndex(A0)
_GetCatInfo
bne.s @MustUpdate
move.l ioFlMdDat(A0),D0 ;was it modified?
cmp.l NDModDate,D0
beq.s @MenuWasAdded
@MustUpdate
bsr UpdateOurMenu
@MenuWasAdded
move.l #10,D7 ;find an empty menu ID
@0 clr.l -(SP) ;is this used?
move.w D7,-(SP)
_GetMHandle
tst.l (SP)+
beq.s @1
addq #1,D7 ;nope, try the next number
bra.s @0
@1 lea NSMenuID,A0 ;OK, got our empty menu ID. Save it and set it!
move.w D7,(A0)
move.l NSMenu,A0
move.l (A0),A0
move.w NSMenuID,menuID(A0)
clr.l -(SP)
move.w #257,-(SP) ;Can we find the file menu?
_GetMHandle
move.l (SP)+,D6
tst.l D6
beq.s @Done
move.l D6,-(SP) ;ok, tell it that New now has a hierarchical menu!
move.w #1,-(SP)
move.w #$1B,-(SP)
_SetItemCmd
move.l D6,-(SP)
move.w #1,-(SP)
move.w D7,-(SP)
_SetItmMark
move.l D6,-(SP)
move.w #1,-(SP)
pea NewMenuText
_SetItem
move.l NSMenu,-(SP) ;attach ourselves!
move.w #-1,-(SP)
_InsertMenu
move.l NSMenu,A0 ;and fill in our proc
move.l (A0),A0
move.l D6,A1
move.l (A1),A1
move.l 6(A1),6(A0) ;the menuproc is 6 bytes in.
move.l NSMenu,-(SP)
_CalcMenuSize
@Done
rts
;
; MyMenuSelect. If we're not in the finder, just call the real trap. Otherwise,
; add our menu if necessary, call the real trap, and handle us if it's us!
;
MyMenuSelect
link A6,#-260
movem.l D2-D7/A2-A4,-(SP)
bsr CheckFinder ;are we in the finder?
bne.s @BailOut
bsr AddUsIn ;pur our menus in place
clr.l -(SP)
move.l 8(A6),-(SP)
move.l jMenuSelect,A0
jsr (A0)
move.l (SP)+,12(A6)
move.w NSMenuID,-(SP) ;remove our menu
_DeleteMenu
move.w 12(A6),D0 ;was it our menu?
cmp.w NSMenuID,D0
bne.s @999
move.w 14(A6),D0 ;find out which one it was
cmp.w #1,D0 ;if #1, it's New Folder
bne.s @100
move.l #$01010001,12(A6) ;make it the "real" NewFolder
bra.s @999
@100 move.l NSMenu,-(SP) ;yup. Get the text
move.w 14(A6),-(SP)
pea NameToCopy
_GetItem
lea AreWeWatching,A0 ;and flag that we want a copy
move.w #1,(A0)
move.l #$01010001,12(A6) ;and start the copy by having the finder make a new folder
@999 movem.l (SP)+,D2-D7/A2-A4
unlk A6
move.l (SP)+,A0
move.l (SP)+,D1 ;throw out old param
jmp (A0)
@BailOut
movem.l (SP)+,D2-D7/A2-A4 ;restore the stack
unlk A6
move.l jMenuSelect, A1
jmp (A1)
;
; MyMenuKey. Just like MyMenuSelect, except uses the keys
;
MyMenuKey
link A6,#-260
movem.l D2-D7/A2-A4,-(SP)
bsr CheckFinder ;are we in the finder?
bne.s @BailOut
bsr AddUsIn ;pur our menus in place
clr.l -(SP)
move.w 8(A6),-(SP)
move.l jMenuKey,A0
jsr (A0)
move.l (SP)+,10(A6)
move.w NSMenuID,-(SP) ;remove our menu
_DeleteMenu
move.w 10(A6),D0 ;was it our menu?
cmp.w NSMenuID,D0
bne.s @999
move.w 12(A6),D0 ;find out which one it was
cmp.w #1,D0 ;if #1, it's New Folder
bne.s @100
move.l #$01010001,10(A6) ;make it the "real" NewFolder
bra.s @999
@100 move.l NSMenu,-(SP) ;yup. Get the text
move.w 12(A6),-(SP)
pea NameToCopy
_GetItem
lea AreWeWatching,A0 ;and flag that we want a copy
move.w #1,(A0)
move.l #$01010001,10(A6) ;and start the copy by having the finder make a new folder
@999 movem.l (SP)+,D2-D7/A2-A4
unlk A6
move.l (SP)+,A0
move.w (SP)+,D1 ;throw out old param
jmp (A0)
@BailOut
movem.l (SP)+,D2-D7/A2-A4 ;restore the stack
unlk A6
move.l jMenuKey, A1
jmp (A1)
;
;
; MyHFSDispatch. We only want to watch when a new folder is created, and snarf away
; away the vrefnum and dirID.
;
MyHFSDispatch
link A6,#-260
movem.l D0-D2/A0,-(SP)
cmp.w #6,D0
bne.s @BailOut
lea AreWeWatching,A1 ;see if we want to store this
cmpi.w #1,(A1)
bne.s @BailOut
move.w ioVrefnum(A0),2(A1)
move.l ioDirID(A0),4(A1)
move.w #2,(A1)
move.l ioFileName(A0),A0
lea LastName,A1
moveq #32,D0
_BlockMove
movem.l (SP)+,D0-D2/A0 ;restore the stack
unlk A6
move.w #-1,D0
move.w D0,ioResult(A0)
rts
@BailOut
movem.l (SP)+,D0-D2/A0 ;restore the stack
unlk A6
move.l jHFSDisptch, A1
jmp (A1)
;
; We've patched Alert to hide the Finder's error messages
;
MyAlert
lea AreWeWatching,A1 ;see if we are ready to copy!
cmpi.w #2,(A1)
beq.s @EatAlert
cmpi.w #3,(A1)
bne.s @900
clr.w (A1)
@EatAlert
move.l (SP)+,A0
adda.l #6,SP
move.w #1,(SP) ;return "OK"
jmp (A0)
@900 move.l jAlert,A0
jmp (A0)
;
;
; MySystemTask. When we've got a 2 in the watching marker, we delete the folder and
; copy the file!
;
MySystemTask
link A6,#-1024
movem.l D2-D7/A2-A4,-(SP)
lea AreWeWatching,A1 ;see if we are ready to copy!
cmpi.w #2,(A1)
bne @BailOut
move.w #3,(A1) ;OK, do it!
lea -1024(A6),A0 ;delete the old folder
lea LastName,A1
move.l A1,ioFileName(A0)
move.w Lastvrefnum,ioVrefnum(A0)
move.l LastDirID,ioDirID(A0)
_HDelete
clr.l D7 ;make a new file with a new name
@NameLoop
lea NameToCopy,A0
lea LastName,A1
moveq #32,D0
_BlockMove
tst.w D7 ;is this the first one?
beq.s @50
lea LastName,A1 ;nope, add the digit
clr.l D0
move.b (A1),D0
addq #1,D0
move.b D0,(A1)
move.b D7,D1
add.b #$30,D1
move.b D1,+0(A1,D0.w)
@50 lea -1024(A6),A0 ;create the new file
lea LastName,A1
move.l A1,ioFileName(A0)
move.w Lastvrefnum,ioVrefnum(A0)
move.l LastDirID,ioDirID(A0)
_HCreate
cmpi.w #-48,D0 ;make sure that we didn't have a duplicate
bne.s @100
addq #1,D7
bra.s @NameLoop ;got a dup. Try next number
@100
lea FromPB,A0 ;Get type and creator of the original
lea NameToCopy,A1
move.l A1,ioFileName(A0)
move.w NDVref,ioVrefnum(A0)
move.l NDDir,ioDirID(A0)
clr.w ioFDirIndex(A0)
_HGetFileInfo
lea ToPB,A0 ;Set it to the copy
lea LastName,A1
move.l A1,ioFileName(A0)
move.w Lastvrefnum,ioVrefnum(A0)
move.l LastDirID,ioDirID(A0)
clr.w ioFDirIndex(A0)
_HGetFileInfo
lea ToPB,A0
lea LastName,A1
move.l A1,ioFileName(A0)
move.w Lastvrefnum,ioVrefnum(A0)
move.l LastDirID,ioDirID(A0)
move.l FromPB+ioFlUsrWds, ioFlUsrWds(A0) ;copy the type and creator
move.l FromPB+ioFlUsrWds+4, ioFlUsrWds+4(A0) ;copy the type and creator
move.l FromPB+ioFlMdDat, ioFlMdDat(A0) ;copy the modification date
move.l FromPB+ioFlCrDat, ioFlCrDat(A0) ;copy the creation date
_HSetFileInfo
lea FromPB,A0 ;OK, open them both to copy!
lea NameToCopy,A1
move.l A1,ioFileName(A0)
move.w NDVref,ioVrefnum(A0)
move.l NDDir,ioDirID(A0)
clr.b 27(A0)
_HOpen
lea ToPB,A0
lea LastName,A1
move.l A1,ioFileName(A0)
move.w Lastvrefnum,ioVrefnum(A0)
move.l LastDirID,ioDirID(A0)
clr.b 27(A0)
_HOpen
move.l FromPB+ioFlLgLen,D7 ;find out how many bytes to copy
bsr.s CopyFork
lea FromPB,A0 ;Now copy the resource fork
lea NameToCopy,A1
move.l A1,ioFileName(A0)
move.w NDVref,ioVrefnum(A0)
move.l NDDir,ioDirID(A0)
clr.b 27(A0)
_HOpenRF
lea ToPB,A0
lea LastName,A1
move.l A1,ioFileName(A0)
move.w Lastvrefnum,ioVrefnum(A0)
move.l LastDirID,ioDirID(A0)
clr.b 27(A0)
_HOpenRF
move.l FromPB+ioFlRLgLen,D7 ;find out how many bytes to copy
bsr.s CopyFork
lea -1024(A6),A0 ;flush the volume!
clr.l ioFileName(A0)
move.w Lastvrefnum, ioVrefnum(A0)
_FlushVol
@BailOut
movem.l (SP)+,D2-D7/A2-A4 ;restore the stack
unlk A6
move.l jSystemTask, A1
jmp (A1)
;
; Copy Fork. We have two paramblocks, in FromPB and ToPB, already open. The
; number of bytes to copy is in D7
;
CopyFork
movem.l D5-D6/A4,-(SP)
tst.l D7
beq.s @Done
move.l D7,D6 ;get a buffer in RAM
@AllocateLoop
move.l D6,D0
_NewPtr
cmpa.l #0,A0 ;did we get one?
bne.s @GotBuffer
divu #2,D6 ;try half that size
cmp.l #1024,D6 ;if we couldn't get 1k buffer, give up!
bgt.s @AllocateLoop
bra.s @Done
@GotBuffer
move.l A0,A4 ;save this
@CopyLoop
move.l D6,D5 ;copy a buffer's worth
cmp.l D5,D7 ;or a partial buffer's worth
bge.s @100
move.l D7,D5
@100
lea FromPB,A0
move.l A4,ioBuffer(A0)
move.l D5,ioReqCount(A0)
clr.w ioPosMode(A0)
_Read
lea ToPB,A0
move.l A4,ioBuffer(A0)
move.l D5,ioReqCount(A0)
clr.w ioPosMode(A0)
_Write
sub.l D5,D7
cmp.l #0,D7
bgt.s @CopyLoop
move.l A4,A0
_DisposePtr
@Done
lea FromPB,A0
_Close
lea ToPB,A0
_Close
movem.l (SP)+,D5-D6/A4
rts
;
; Check to see if we're in the finder
;
CheckFinder
move.b CurApName,D0 ;see if it's still INITting
cmp.b #$FF,D0
beq.s @0
LEA CurApName,A0 ;check on FinderName
move.b (A0)+,D0 ;set up for _CmpString
swap D0
LEA FinderName,A1
move.B (A1)+,D0
AndI.L #$00FF00FF,D0
_CmpString ,MARKS
Cmp.W #0,D0
@0 RTS
;
; Installation code. Copy our code into the system heap, save the resources, and
; quit.
;
Install link A6,#-128
movem.l A3,-(SP)
btst #0,KeyMap+7 ;see if shift key's down
bne @999 ;if so, don't install
import ShowInit
move.w #128,-(SP) ;show our init
move.w #-1,-(SP)
bsr ShowInit
move.L #Install-StartofInit,D0
_NewPtr ,SYS ;get a block in the system heap
move.L A0,A3 ;save the pointer
move.L A0,A1 ;copy stuff over
LEA StartofInit,A0
move.L #Install-StartofInit,D0
_BlockMove
clr.l -(SP) ;get our handle to the menu
move.l #'MENU',-(SP)
move.w #10,-(SP)
_GetResource
move.l (SP),NSMenu-StartofInit(A3)
_DetachResource
clr.l -(SP) ;Set our strings
move.l #'STR ',-(SP)
move.w #10,-(SP) ;this is the name of the folder with the docs
_GetResource
move.l (SP)+,A0
move.l (A0),A0
lea NDName-StartofInit(A3),A1
moveq #32,D0
_BlockMove
clr.l -(SP)
move.l #'STR ',-(SP)
move.w #11,-(SP) ;this is what we change the NewFolder menu item to
_GetResource
move.l (SP)+,A0
move.l (A0),A0
lea NewMenuText-StartofInit(A3),A1
moveq #32,D0
_BlockMove
move.w #$13D,D0 ;patch MenuSelect
_GetTrapAddress ,NEWTOOL
lea jMenuSelect-StartofInit(A3),A1
move.l A0,(A1)
move.w #$13D,D0
lea MyMenuSelect-StartofInit(A3),A0
_SetTrapAddress ,NEWTOOL
move.w #$13E,D0 ;patch MenuKey
_GetTrapAddress ,NEWTOOL
lea jMenuKey-StartofInit(A3),A1
move.l A0,(A1)
move.w #$13E,D0
lea MyMenuKey-StartofInit(A3),A0
_SetTrapAddress ,NEWTOOL
move.w #$60,D0 ;patch HFSDispatch
_GetTrapAddress ,NEWOS
lea jHFSDisptch-StartofInit(A3),A1
move.l A0,(A1)
move.w #$60,D0
lea MyHFSDispatch-StartofInit(A3),A0
_SetTrapAddress ,NEWOS
move.w #$1B4,D0 ;patch SystemTask
_GetTrapAddress ,NEWTOOL
lea jSystemTask-StartofInit(A3),A1
move.l A0,(A1)
move.w #$1B4,D0
lea MySystemTask-StartofInit(A3),A0
_SetTrapAddress ,NEWTOOL
move.W #$185,D0 ;Next is Alert
_GetTrapAddress ,NEWTOOL
lea jAlert-StartofInit(A3),A1
move.l A0,(A1)
move.w #$185,D0 ;and patch ourselves in!
LEA MyAlert-StartofInit(A3),A0
_SetTrapAddress ,NEWTOOL
clr.w -(SP)
_CurResFile
lea -128(A6),A0 ;get the file name and location
clr.w ioFCBIndx(A0)
move.w (SP)+,ioRefNum(A0)
lea MyName-StartofInit(A3),A1
move.l A1,ioFileName(A0)
clr.b (A1)
_GetFCBInfo
lea MyDir-StartofInit(A3),A1
move.l ioFCBParID(A0),(A1)+
move.w ioFCBVRefNum(A0),(A1)+
@999 movem.l (SP)+,A3
unlk A6
rts
end